"""
基础单位类定义
包含所有游戏单位的基本属性和方法，不包含环境相关逻辑

作者:wjttdbx
版本:3.0 - 重构版本，使用工具模块，简化设计
"""
import math
from typing import List, Tuple, Optional
from .config import GameConfig
from .utils import distance_between_points, normalize_angle, angle_difference, is_in_sector


class Unit:
    """
    基础单位类
    
    所有游戏单位（白方无人艇、无人机、黑方无人艇）的基类。
    包含单位的基本属性和通用方法。
    
    Attributes:
        id (int): 单位唯一标识符
        x (float): X坐标位置（米）
        y (float): Y坐标位置（米）  
        unit_type (str): 单位类型标识
        active (bool): 单位是否存活/激活
        locked_times (int): 被锁定次数
        freeze_until (float): 冻结结束时间戳
        last_lock_time (float): 上次被锁定时间
        heading (float): 航向角（弧度，0为正东方向）
        speed (float): 当前速度（m/s）
        max_speed (float): 最大速度（m/s）
        min_turn_radius (float): 最小转弯半径（米）
        detected_targets (List[Unit]): 探测到的目标列表
    """
    
    def __init__(self, unit_id: int, x: float, y: float, unit_type: str, max_speed: float, min_turn_radius: float, max_acceleration: float = 2.0):
        """
        初始化单位
        
        Args:
            unit_id (int): 单位唯一ID
            x (float): 初始X坐标
            y (float): 初始Y坐标
            unit_type (str): 单位类型（'white_boat', 'black_boat', 'white_drone'）
            max_speed (float): 最大速度（m/s）
            min_turn_radius (float): 最小转弯半径（米）
        """
        # 基本属性
        self.id = unit_id
        self.x = x
        self.y = y
        self.unit_type = unit_type
        self.active = True
        
        # 锁定相关属性
        self.locked_times = 0
        self.freeze_until = 0.0
        self.last_lock_time = 0.0
        
        # 运动学属性
        self.heading = 0.0
        self.speed = 0.0
        self.max_speed = max_speed
        self.min_turn_radius = min_turn_radius
        self.max_acceleration = max_acceleration  # 最大加速度（m/s²）
        
        # 锁定系统属性
        self.current_target = None
        self.lock_start_time = 0
        self.is_locking = False
        self.detected_targets = []  # 直接使用列表存储探测到的单位对象

    def get_position(self) -> Tuple[float, float]:
        """获取单位当前位置"""
        return self.x, self.y
    
    def is_frozen(self, current_time: float) -> bool:
        """检查单位是否处于冻结状态"""
        return current_time < self.freeze_until
    
    def distance_to(self, other) -> float:
        """计算到另一个单位的欧几里得距离"""
        return distance_between_points(self.x, self.y, other.x, other.y)
    
    def move_with_kinematics(self, target_speed: float, target_heading: float, dt: float):
        """
        运动学约束移动方法（适用于所有单位）
        参数：
            target_speed (float): 目标速度（m/s），应为绝对速度，范围[0, max_speed]
            target_heading (float): 目标航向角（弧度，0为正东方向，逆时针为正）
            dt (float): 时间步长（秒）
        约束：
            - 速度强制在[0, max_speed]区间
            - 速度变化受最大加速度约束
            - 转向角变化受最小转弯半径和当前速度影响
            - 静止时可瞬时转向
        """
        # 速度约束
        target_speed = max(0, min(target_speed, self.max_speed))
        # 加速度约束
        max_acc = self.max_acceleration if hasattr(self, 'max_acceleration') and self.max_acceleration is not None else 2.0
        delta_v = target_speed - self.speed
        max_delta_v = max_acc * dt
        if abs(delta_v) > max_delta_v:
            target_speed = self.speed + max_delta_v * (1 if delta_v > 0 else -1)
        # 航向角约束（考虑最小转弯半径）
        if self.speed > 0:
            # 计算最大转向角速度
            max_angular_velocity = self.speed / self.min_turn_radius
            max_heading_change = max_angular_velocity * dt
            
            # 限制航向角变化
            heading_diff = angle_difference(target_heading, self.heading)
            heading_diff = max(-max_heading_change, min(max_heading_change, heading_diff))
            self.heading = normalize_angle(self.heading + heading_diff)
        else:
            self.heading = normalize_angle(target_heading)
        # 更新速度和位置
        self.speed = target_speed
        self.x += self.speed * math.cos(self.heading) * dt
        self.y += self.speed * math.sin(self.heading) * dt
    
    def start_locking(self, target, current_time: float):
        """开始锁定目标"""
        if self.current_target != target:
            self.current_target = target
            self.lock_start_time = current_time
            self.is_locking = True
    
    def stop_locking(self):
        """停止锁定"""
        self.current_target = None
        self.lock_start_time = 0
        self.is_locking = False
    
    def get_lock_duration(self, current_time: float) -> float:
        """获取当前锁定持续时间"""
        if self.is_locking and self.current_target:
            return current_time - self.lock_start_time
        return 0.0
    



class WhiteBoat(Unit):
    """
    白方无人艇类
    
    负责区域封锁的主要作战单位。每艘无人艇可以携带一架无人机，
    具备探测、锁定黑方目标的能力。
    
    能力特性：
        - 机动速度: 10m/s
        - 探测距离: 20km  
        - 锁定距离: 40km
        - 锁定成功率: 0.8
        - 可携带1架无人机
    

    """
    
    def __init__(self, unit_id: int, x: float, y: float):
        """初始化白方无人艇"""
        super().__init__(unit_id, x, y, "white_boat", 
                        GameConfig.WHITE_BOAT_MAX_SPEED, 
                        GameConfig.WHITE_BOAT_MIN_TURN_RADIUS,
                        max_acceleration=GameConfig.WHITE_BOAT_MAX_ACCELERATION)  # 无人艇最大加速度2m/s²



class WhiteDrone(Unit):
    """
    白方无人机类
    
    侦察单位，具备更远的探测距离和更快的速度，但留空时间有限。
    需要定期返回母舰补能。
    
    能力特性：
        - 飞行速度: 20-150m/s
        - 探测距离: 60km
        - 留空时间: 2小时
        - 补能时间: 5小时
        - 可在任意白方无人艇上降落
    
    Attributes:
        parent_boat_id (int): 初始母舰ID
        docked_on_boat_id (Optional[int]): 当前停靠的母舰ID，None表示在空中
        flight_start_time (float): 起飞时间戳
        recharge_start_time (float): 开始补能时间戳
        state (str): 当前状态 ('flying', 'recharging', 'returning')
        energy (float): 当前能量（0-100%）
        max_energy (float): 最大能量
        energy_consumption_rate (float): 能耗速率（%/秒）
        recharge_rate (float): 补能速率（%/秒）
        min_speed (float): 最小飞行速度
    """
    
    def __init__(self, unit_id: int, x: float, y: float, parent_boat_id: int):
        """初始化白方无人机"""
        super().__init__(unit_id, x, y, "white_drone", 
                        GameConfig.WHITE_DRONE_MAX_SPEED, 
                        GameConfig.WHITE_DRONE_MIN_TURN_RADIUS,
                        max_acceleration=GameConfig.WHITE_DRONE_MAX_ACCELERATION)  # 无人机最大加速度10m/s²
        
        # 无人机特有属性
        self.min_speed = GameConfig.WHITE_DRONE_MIN_SPEED
        self.parent_boat_id = parent_boat_id
        self.docked_on_boat_id = parent_boat_id  # 初始时停靠在母舰上
        self.flight_start_time = 0.0
        self.recharge_start_time = 0.0
        self.state = "recharging"  #  flying, recharging, returning
        
        # 能量系统
        self.energy = 100.0
        self.max_energy = 100.0
        self.energy_consumption_rate = 100.0 / GameConfig.WHITE_DRONE_FLIGHT_TIME
        self.recharge_rate = 100.0 / GameConfig.WHITE_DRONE_RECHARGE_TIME
        
    def update_energy(self, dt: float, parent_boat_frozen: bool = False):
        """更新能量状态"""
        if self.state in ["flying", "returning"]:
            # 飞行时消耗能量
            self.energy = max(0, self.energy - self.energy_consumption_rate * dt)
        elif self.state == "recharging" and not parent_boat_frozen:
            # 补能时恢复能量（母舰未冻结）
            self.energy = min(self.max_energy, self.energy + self.recharge_rate * dt)
            
    def is_target_in_detection_sector(self, target, current_heading: float) -> bool:
        """检查目标是否在60°扇形探测范围内"""
        return is_in_sector(
            self.x, self.y, current_heading,
            target.x, target.y,
            math.radians(GameConfig.WHITE_DRONE_DETECT_ANGLE),
            GameConfig.WHITE_DRONE_DETECT_RANGE
        )
    

    

        

        
    

    
    def move_with_kinematics(self, target_speed: float, target_heading: float, dt: float):
        """
        无人机运动学约束移动方法（重写父类方法）
        - 飞行/返航时速度不能低于min_speed
        - 其它状态速度可为0
        - 速度变化受最大加速度约束
        - 其它约束同Unit
        """
        if self.state in ["flying", "returning"]:
            target_speed = max(self.min_speed, min(target_speed, self.max_speed))
        else:
            target_speed = max(0, min(target_speed, self.max_speed))
        
        # 调用父类方法
        super().move_with_kinematics(target_speed, target_heading, dt)


class BlackBoat(Unit):
    """
    黑方无人艇类
    
    试图穿越封锁区域的目标单位。具备一定的探测和锁定能力，
    但主要目标是从区域一侧穿越到另一侧。
    
    能力特性：
        - 机动速度: 10m/s
        - 探测距离: 30km
        - 锁定距离: 40km  
        - 锁定成功率: 0.8
        - 无法探测/锁定无人机
        - 目标：穿越到区域右侧边界
    
    Attributes:
        crossed (bool): 是否成功穿越封锁线
    """
    
    def __init__(self, unit_id: int, x: float, y: float):
        """初始化黑方无人艇"""
        super().__init__(unit_id, x, y, "black_boat", 
                        GameConfig.BLACK_BOAT_MAX_SPEED, 
                        GameConfig.BLACK_BOAT_MIN_TURN_RADIUS,
                        max_acceleration=GameConfig.BLACK_BOAT_MAX_ACCELERATION)  # 黑方无人艇最大加速度2m/s²
        self.crossed = False  # 是否成功穿越 